import { ProFormDatePicker, ProFormInstance, ProFormSelect, QueryFilter } from '@/components/Pro/';
import { strategyTrackControllerGetStrategyLineData as getData } from '@/services/ess/strategyTrack';
import { Spin } from 'antd';
import dayjs from 'dayjs';
import ReactEcharts from 'echarts-for-react';
import { throttle } from 'lodash';
import moment from 'moment';
import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useIntl, useModel } from 'umi';

const TEXT_COLOR = '#222';
const POWER_UNIT = 'kW';
const times = [...new Array(24 * 60 * 60)].map((i, index) =>
  dayjs().startOf('date').add(index, 'second').format('HH:mm:ss'),
);
const initChartData = {
  legendConf: [],
  seriesData: [],
  isEmpty: false,
};

const Echarts = memo(({ chartData }) => {
  const intl = useIntl();
  const chartRef = useRef();

  useEffect(() => {
    const resizeHandler = throttle(() => {
      chartRef?.current?.getEchartsInstance()?.resize();
    }, 200);

    window.addEventListener('resize', resizeHandler);
    return () => {
      window.removeEventListener('resize', resizeHandler);
    };
  }, []);

  const datasLen = chartData.legendConf?.length - 1 ?? 0;
  const chartOption = useMemo(
    () => ({
      dataZoom: [
        {
          type: 'inside',
          throttle: 50,
        },
      ],
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow',
        },
        formatter: function (params) {
          if (chartData.isEmpty) {
            return '';
          }
          let text = `<div>${params[0].axisValueLabel}<br/>`;
          (params || []).forEach((item) => {
            const originalData =
              item.data.originalValue !== undefined ? item.data.originalValue : item.value;
            text += `${item.data.show === false ? '' : item.marker}${item.seriesName}`;
            if (originalData || originalData === 0) {
              text += `&nbsp;:&nbsp;&nbsp;${originalData}${item.data.unit}<br/>`;
            } else {
              text += `&nbsp;:&nbsp;&nbsp;<br/>`;
            }
          });
          text += '</div>';
          return text;
        },
      },
      legend: chartData.legendConf,
      grid: {
        left: 20,
        right: 20,
        bottom: 10,
        top: 60 + datasLen * 25,
        containLabel: true,
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: times,
        nameTextStyle: {
          color: '#222',
        },
        axisTick: {
          alignWithLabel: true,
          show: true,
          inside: true,
        },
        axisLine: {
          show: true,
          lineStyle: {
            color: '#ddd',
          },
          onZero: false,
        },
        axisLabel: {
          color: TEXT_COLOR,
          formatter: function (value) {
            const formatVal = value?.substring(0, 2);
            return formatVal === '00' ? '0' : formatVal;
          },
          interval: 60 * 60 - 1,
        },
      },
      yAxis: [
        {
          type: 'value',
          name: POWER_UNIT,
          position: 'left',
          alignTicks: true,
          max: chartData.isEmpty ? 100 : null,
          min: chartData.isEmpty ? 0 : null,
          axisLine: {
            show: true,
            lineStyle: {
              color: '#ddd',
            },
          },
          nameTextStyle: {
            color: TEXT_COLOR,
            align: 'left',
          },
          axisLabel: {
            formatter: (value) => {
              return value > -1 && value < 1 && value !== 0 ? value?.toFixed(2) : value?.toFixed(0);
            },
            color: TEXT_COLOR,
          },
          splitLine: {
            show: false,
          },
          axisTick: {
            show: true,
            inside: true,
          },
        },
        {
          type: 'value',
          name: 'SOC(%)',
          position: 'right',
          alignTicks: true,
          min: 0,
          max: 100,
          axisLine: {
            show: true,
            lineStyle: {
              color: '#ddd',
            },
          },
          nameTextStyle: {
            color: TEXT_COLOR,
            align: 'right',
          },
          axisLabel: {
            formatter: (value) => {
              return value?.toFixed(0);
            },
            color: TEXT_COLOR,
          },
          splitLine: {
            show: false,
          },
          axisTick: {
            show: true,
            inside: true,
          },
        },
      ],
      series: chartData.seriesData.map((series) => ({
        ...series,
        sampling: 'average',
        tooltip: {
          trigger: 'axis',
          formatter: function (params) {
            const originalData = series.data[params[0].dataIndex];
            return `${params[0].axisValueLabel}<br/>
                    ${params[0].marker}${params[0].seriesName}: ${originalData.originalValue}`;
          },
        },
        data: series.data.map((item, index) => ({
          ...item,
          originalValue: item.value,
          value: item.value,
          dataIndex: index,
        })),
      })),
      graphic: [
        {
          type: 'image',
          silent: true,
          style: {
            image: require('@/assets/img/empty.png'),
            width: 180,
            height: 120,
          },
          bounding: 'raw',
          top: 'center',
          left: 'center',
          invisible: !chartData.isEmpty,
        },
        {
          type: 'text',
          left: 'center',
          top: 320,
          silent: true,
          invisible: !chartData.isEmpty,
          style: {
            fill: '#222',
            text: intl.formatMessage({
              id: 'global.noDataYet',
            }),
            fontFamily: 'Microsoft YaHei',
            fontSize: '14px',
          },
        },
      ],
    }),
    [chartData, intl, datasLen],
  );

  return (
    <ReactEcharts
      ref={chartRef}
      style={{ height: `${500 + datasLen * 25}px` }}
      notMerge={true}
      option={chartOption}
    />
  );
});

const StrategyChart: React.FC = ({ areaList }) => {
  const intl = useIntl();
  const formRef = useRef<ProFormInstance>();

  const { stationId, isArea } = useModel('@@initialState')?.initialState || {};
  const [loading, setLoading] = useState(true);
  const [chartData, setChartData] = useState(initChartData);

  const processChartData = useCallback(
    (data) => {
      let tempLegendConf = [];
      let tempSeriesData = [];
      let tempEmpty = true;

      (data ?? []).forEach((item, index) => {
        const {
          targetPowerList,
          socList,
          activePowerList,
          workStateList,
          locationName,
          loadPowerList,
          demandList,
          fenggu,
        } = item ?? {};

        const areaName = isArea ? locationName + '-' : '';

        const activeInRealTimeName = `${areaName}${intl.formatMessage({
          id: 'strategyControl.strategyTracking.energyStorageIsActiveInRealTime',
        })}`;
        const socName = `${areaName}${intl.formatMessage({
          id: 'strategyControl.strategyTracking.soc',
        })}`;
        const gridSupplyPointLoadName = `${areaName}${intl.formatMessage({
          id: 'strategyControl.strategyTracking.gridSupplyPointLoad',
        })}`;
        const targetActivePowerName = `${areaName}${intl.formatMessage({
          id: 'strategyControl.strategyTracking.targetActivePower',
        })}`;
        const demandName = `${areaName}${intl.formatMessage({
          id: 'strategyControl.strategyTracking.demand',
        })}`;

        tempLegendConf.push({
          type: 'scroll',
          orient: 'horizontal',
          top: index * 25,
          right: 44,
          icon: 'circle',
          data: [
            activeInRealTimeName,
            socName,
            gridSupplyPointLoadName,
            targetActivePowerName,
            demandName,
          ],
        });

        let opacity = 1;
        if (index === 1) {
          opacity = 0.75;
        }
        if (index === 2) {
          opacity = 0.55;
        }
        if (index === 3) {
          opacity = 0.35;
        }
        if (index > 3) {
          opacity = 0;
        }

        tempSeriesData.push(
          ...[
            {
              name: `${areaName}${intl.formatMessage({
                id: 'strategyControl.strategyTracking.chargeOrDischarge',
              })}`,
              type: 'line',
              data: (workStateList || []).map((v) => ({
                value: v,
                unit: '',
                show: false,
              })),
              show: false,
            },
            {
              name: activeInRealTimeName,
              type: 'line',
              data: (activePowerList || []).map((v) => ({
                value: v,
                originalValue: v, // Store the original value
                unit: POWER_UNIT,
              })),
              smooth: true,
              symbol: 'none',
              itemStyle: {
                normal: {
                  color: opacity === 0 ? null : `rgba(26,108,254,${opacity})`,
                  lineStyle: {
                    color: opacity === 0 ? null : `rgba(26,108,254,${opacity})`,
                  },
                },
              },
            },
            {
              name: socName,
              type: 'line',
              data: (socList || []).map((v) => ({
                value: v,
                unit: '%',
              })),
              yAxisIndex: 1,
              smooth: true,
              symbol: 'none',
              color: '#FF7A0C',
              itemStyle: {
                normal: {
                  color: opacity === 0 ? null : `rgba(103,194,58,${opacity})`,
                  lineStyle: {
                    color: opacity === 0 ? null : `rgba(103,194,58,${opacity})`,
                  },
                },
              },
            },
            {
              name: gridSupplyPointLoadName,
              type: 'line',
              data: (loadPowerList || []).map((v) => ({
                value: v,
                unit: POWER_UNIT,
              })),
              smooth: true,
              symbol: 'none',
              itemStyle: {
                normal: {
                  color: opacity === 0 ? null : `rgba(255,213,12,${opacity})`,
                  lineStyle: {
                    color: opacity === 0 ? null : `rgba(255,213,12,${opacity})`,
                  },
                },
              },
            },
            {
              name: targetActivePowerName,
              type: 'line',
              data: (targetPowerList || []).map((v) => ({
                value: v,
                unit: POWER_UNIT,
              })),
              smooth: true,
              symbol: 'none',
              itemStyle: {
                normal: {
                  color: opacity === 0 ? null : `rgba(241,72,59,${opacity})`,
                  lineStyle: {
                    color: opacity === 0 ? null : `rgba(241,72,59,${opacity})`,
                  },
                },
              },
            },
          ],
        );

        if (
          (workStateList || []).find((v) => v !== null) ||
          (targetPowerList || []).find((v) => v !== null) ||
          (socList || []).find((v) => v !== null) ||
          (activePowerList || []).find((v) => v !== null) ||
          (loadPowerList || []).find((v) => v !== null)
        ) {
          tempEmpty = false;
        }

        tempSeriesData.push({
          name: demandName,
          type: 'line',
          data: (demandList || []).map((v) => ({
            value: v,
            unit: POWER_UNIT,
          })),
          smooth: true,
          symbol: 'none',
          itemStyle: {
            normal: {
              color: opacity === 0 ? null : `rgba(147,112,219,${opacity})`,
              lineStyle: {
                color: opacity === 0 ? null : `rgba(147,112,219,${opacity})`,
              },
            },
          },
        });

        const getTimeTypeConfig = (type) => {
          switch (type) {
            case 1:
              return {
                borderColor: '#FF7A0C',
                label: intl.formatMessage({ id: 'strategyControl.strategyTracking.sharp' }),
              };
            case 2:
              return {
                borderColor: '#FF7A0C',
                label: intl.formatMessage({ id: 'strategyControl.strategyTracking.peak' }),
              };
            case 3:
              return {
                borderColor: '#B4CDFF',
                label: intl.formatMessage({ id: 'strategyControl.strategyTracking.shoulder' }),
              };
            case 4:
              return {
                borderColor: '#B4CDFF',
                label: intl.formatMessage({ id: 'strategyControl.strategyTracking.offPeak' }),
              };
            default:
              return {
                borderColor: '#B4CDFF',
                label: '',
              };
          }
        };

        const generateMarkAreas = () => {
          if (!fenggu?.length) return [];

          // 获取当前日期的月份
          const currentMonth = moment(formRef.current?.getFieldValue('date')).month() + 1;

          // 过滤出当前月份适用的时段
          const validPeriods = fenggu.filter((period) => {
            const months = period.months.split(',').map(Number);
            return months.includes(currentMonth);
          });

          // 按开始时间排序
          validPeriods.sort((a, b) => {
            return a.startTime.localeCompare(b.startTime);
          });

          return validPeriods.map((period) => {
            const timeConfig = getTimeTypeConfig(period.timeType);

            return [
              {
                xAxis: period.startTime,
                itemStyle: {
                  color: 'rgba(0, 0, 0, 0)',
                  borderColor: timeConfig.borderColor,
                  borderType: 'dashed',
                  borderWidth: [0, 1, 0, 0],
                },
                label: {
                  show: true,
                  position: 'insideTop',
                  distance: 5,
                  color: 'rgba(34,34,34,0.8)',
                  fontSize: 14,
                  formatter: timeConfig.label,
                },
                emphasis: {
                  show: false,
                  label: {
                    show: false, // 鼠标悬停时不显示标签
                  },
                },
              },
              {
                xAxis: period.endTime,
              },
            ];
          });
        };

        // 更新 series 的 markArea 和 markLine 配置
        tempSeriesData = tempSeriesData.map((series) => ({
          ...series,
          markArea: {
            silent: false,
            data: generateMarkAreas(),
          },
          markLine: {
            silent: true,
            symbol: 'none',
            lineStyle: {
              color: '#B4CDFF',
              type: 'dashed',
              width: 1,
            },
            label: {
              show: false,
            },
            data:
              fenggu?.map((period) => ({
                xAxis: period.startTime,
              })) || [],
          },
        }));
      });

      return { isEmpty: tempEmpty, legendConf: tempLegendConf, seriesData: tempSeriesData };
    },
    [intl, isArea],
  );

  const fetchData = useCallback(() => {
    if (isArea) {
      if (areaList?.[0]?.value) {
        const v = [areaList?.[0]?.value];
        formRef?.current?.setFieldsValue({
          date: moment(),
          areaIdList: v,
        });
        formRef?.current?.submit();
      }
    } else {
      formRef?.current?.setFieldsValue({
        date: moment(),
      });
      formRef?.current?.submit();
    }
  }, [isArea, areaList]);

  useEffect(() => {
    fetchData();
  }, [fetchData]);

  const onFormFinish = useCallback(
    async (value) => {
      setLoading(true);
      try {
        const res = await getData({
          ...value,
          stationId,
        });
        if (res.success) {
          const newChartData = processChartData(res.data);
          setChartData(newChartData);
        } else {
          setChartData({
            ...initChartData,
            isEmpty: true,
          });
        }
      } catch (e) {
        setChartData({
          ...initChartData,
          isEmpty: true,
        });
      }
      setLoading(false);
    },
    [stationId, processChartData],
  );

  return (
    <>
      <div>
        <QueryFilter formRef={formRef} onFinish={onFormFinish} onReset={fetchData}>
          {isArea && (
            <ProFormSelect
              name="areaIdList"
              label={intl.formatMessage({
                id: 'global.area',
              })}
              initialValue={areaList?.[0]?.value && [areaList?.[0]?.value]}
              fieldProps={{
                options: areaList,
                allowClear: false,
                mode: 'multiple',
              }}
            />
          )}
          <ProFormDatePicker
            width={260}
            name="date"
            label={intl.formatMessage({
              id: 'global.date',
            })}
            fieldProps={{
              disabledDate: (current) => {
                return current && current >= dayjs().endOf('day');
              },
              allowClear: false,
            }}
          />
        </QueryFilter>
      </div>
      <Spin spinning={loading}>
        <Echarts chartData={chartData} />
      </Spin>
    </>
  );
};

export default memo(StrategyChart);
